import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { 
  HistoryVersion, 
  FileTreeNode, 
  FileHistoryRecord,
  VersionEntries 
} from '../types/basic'
import { historyParser } from '../services'

export const useHistoryStore = defineStore('history', () => {
  // State
  const versions = ref<HistoryVersion[]>([])
  const currentVersion = ref<string | null>(null)
  const currentVersionFiles = ref<FileTreeNode[]>([])
  const selectedFiles = ref<string[]>([])
  const expandedFolders = ref<Set<string>>(new Set())
  const fileHistoryCache = ref<Map<string, FileHistoryRecord[]>>(new Map())
  const versionEntriesCache = ref<Map<string, VersionEntries>>(new Map())
  const isLoading = ref(false)
  const error = ref<string | null>(null)

  // Services - use the configured instance

  // Getters
  const currentVersionData = computed(() => 
    versions.value.find(v => v.id === currentVersion.value)
  )

  const selectedFileNodes = computed(() => 
    currentVersionFiles.value.filter(file => 
      selectedFiles.value.includes(file.id)
    )
  )

  const hasVersions = computed(() => versions.value.length > 0)

  // Actions
  async function loadVersions() {
    try {
      isLoading.value = true
      error.value = null
      versions.value = await historyParser.scanHistoryVersions()
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载历史版本失败'
      console.error('Failed to load versions:', err)
    } finally {
      isLoading.value = false
    }
  }

  async function selectVersion(versionId: string) {
    if (currentVersion.value === versionId) return

    try {
      isLoading.value = true
      error.value = null
      
      // Load version entries if not cached
      if (!versionEntriesCache.value.has(versionId)) {
        const entries = await historyParser.parseVersionEntries(versionId)
        versionEntriesCache.value.set(versionId, entries)
      }

      const entries = versionEntriesCache.value.get(versionId)!
      currentVersionFiles.value = buildFileTree(entries)
      currentVersion.value = versionId
      
      // Clear previous selections
      selectedFiles.value = []
      expandedFolders.value.clear()
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载版本文件失败'
      console.error('Failed to select version:', err)
    } finally {
      isLoading.value = false
    }
  }

  async function getFileHistory(filePath: string): Promise<FileHistoryRecord[]> {
    if (fileHistoryCache.value.has(filePath)) {
      return fileHistoryCache.value.get(filePath)!
    }

    try {
      const history = await historyParser.getFileHistory(filePath)
      fileHistoryCache.value.set(filePath, history)
      return history
    } catch (err) {
      console.error('Failed to get file history:', err)
      return []
    }
  }

  async function getFileContent(versionId: string, fileId: string): Promise<string> {
    try {
      return await historyParser.getFileContent(versionId, fileId)
    } catch (err) {
      console.error('Failed to get file content:', err)
      throw err
    }
  }

  function toggleFileSelection(fileId: string) {
    const index = selectedFiles.value.indexOf(fileId)
    if (index > -1) {
      selectedFiles.value.splice(index, 1)
    } else {
      selectedFiles.value.push(fileId)
    }
  }

  function selectAllFiles() {
    const allFileIds = getAllFileIds(currentVersionFiles.value)
    selectedFiles.value = [...allFileIds]
  }

  function clearSelection() {
    selectedFiles.value = []
  }

  function toggleFolder(folderPath: string) {
    if (expandedFolders.value.has(folderPath)) {
      expandedFolders.value.delete(folderPath)
    } else {
      expandedFolders.value.add(folderPath)
    }
  }

  function expandAllFolders() {
    const allFolderPaths = getAllFolderPaths(currentVersionFiles.value)
    expandedFolders.value = new Set(allFolderPaths)
  }

  function collapseAllFolders() {
    expandedFolders.value.clear()
  }

  function clearCache() {
    fileHistoryCache.value.clear()
    versionEntriesCache.value.clear()
  }

  function clearError() {
    error.value = null
  }

  async function loadVersionFiles(versionId: string): Promise<FileTreeNode[]> {
    try {
      isLoading.value = true
      error.value = null
      
      // Load version entries if not cached
      if (!versionEntriesCache.value.has(versionId)) {
        const entries = await historyParser.parseVersionEntries(versionId)
        versionEntriesCache.value.set(versionId, entries)
      }

      const entries = versionEntriesCache.value.get(versionId)!
      const files = buildFileTree(entries)
      return files
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载版本文件失败'
      console.error('Failed to load version files:', err)
      return []
    } finally {
      isLoading.value = false
    }
  }

  function getVersionFiles(versionId: string): FileTreeNode[] | null {
    const entries = versionEntriesCache.value.get(versionId)
    if (!entries) return null
    return buildFileTree(entries)
  }

  // Helper functions
  function buildFileTree(entries: VersionEntries): FileTreeNode[] {
    const pathMap = new Map<string, FileTreeNode>()
    const rootNodes: FileTreeNode[] = []

    // Create nodes for all file entries
    entries.entries.forEach(entry => {
      const parts = entry.source?.split('/') || [entry.id]
      let currentPath = ''
      
      parts.forEach((part, index) => {
        const parentPath = currentPath
        currentPath = currentPath ? `${currentPath}/${part}` : part
        
        if (!pathMap.has(currentPath)) {
          const isFile = index === parts.length - 1
          const node: FileTreeNode = {
            id: isFile ? entry.id : currentPath,
            name: part,
            path: currentPath,
            type: isFile ? 'file' : 'folder',
            timestamp: entry.timestamp,
            children: isFile ? undefined : [],
            isExpanded: false
          }
          
          pathMap.set(currentPath, node)
          
          if (parentPath) {
            const parent = pathMap.get(parentPath)
            if (parent && parent.children) {
              parent.children.push(node)
            }
          } else {
            rootNodes.push(node)
          }
        }
      })
    })

    return rootNodes
  }

  function getAllFileIds(nodes: FileTreeNode[]): string[] {
    const fileIds: string[] = []
    
    function traverse(nodes: FileTreeNode[]) {
      nodes.forEach(node => {
        if (node.type === 'file') {
          fileIds.push(node.id)
        } else if (node.children) {
          traverse(node.children)
        }
      })
    }
    
    traverse(nodes)
    return fileIds
  }

  function getAllFolderPaths(nodes: FileTreeNode[]): string[] {
    const folderPaths: string[] = []
    
    function traverse(nodes: FileTreeNode[]) {
      nodes.forEach(node => {
        if (node.type === 'folder') {
          folderPaths.push(node.path)
          if (node.children) {
            traverse(node.children)
          }
        }
      })
    }
    
    traverse(nodes)
    return folderPaths
  }

  return {
    // State
    versions,
    currentVersion,
    currentVersionFiles,
    selectedFiles,
    expandedFolders,
    isLoading,
    error,
    
    // Getters
    currentVersionData,
    selectedFileNodes,
    hasVersions,
    
    // Actions
    loadVersions,
    selectVersion,
    getFileHistory,
    getFileContent,
    loadVersionFiles,
    getVersionFiles,
    toggleFileSelection,
    selectAllFiles,
    clearSelection,
    toggleFolder,
    expandAllFolders,
    collapseAllFolders,
    clearCache,
    clearError
  }
})

// Simple persistence implementation
if (typeof window !== 'undefined') {
  const STORAGE_KEY = 'history-store'
  
  // Load persisted state
  try {
    const stored = localStorage.getItem(STORAGE_KEY)
    if (stored) {
      JSON.parse(stored)
      // Apply persisted state when store is created
      // This would need to be implemented with watchers
    }
  } catch (error) {
    console.warn('Failed to load persisted history state:', error)
  }
}